This document describes the GestaltValue functionality as implemented in GestaltValue.o. Interfaces to GestaltValue are provided in GestaltValue.h and GestaltValue.p.
GestaltValue is a set of routines, implemented as glue, that extend and enhance existing Gestalt functionality. For a complete description of Gestalt, refer to Chapter 3 of Inside Macintosh VI.
Rationale
Existing Gestalt functionality allows developers to put Gestalt to use in their own applications by register a Gestalt selector with using the NewGestalt or ReplaceGestalt calls, and providing a function which can return the appropriate response.
While this is a powerful feature of Gestalt, in practice, it is difficult to take advantage of for a number of reasons:
1) The supplied function must entirely reside in the system heap.
2) The function should be reentrant and not move memory because Gestalt (and therefore the function) may be called at interrupt time.
3) The function must effectively remain resident until restart. This is a problem for applications which may come and go multiple times.
4) Since the purpose of the function is to return a response value, the function must know how to locate, or otherwise manage that value.
All of this means a lot of work just to allow code to retrieve the response value via Gestalt.
GestaltValue addresses all these issues. It is built to deal with the most common case, simply returning a 32-bit value. It safely implements and installs a single common, shared gestalt function and reports back values via the existing Gestalt mechanism. This gestalt function gets installed the first time the glue gets invoked. Subsequent calls to the glue (either from the same application, or a different one) cooperate with the gestalt function to maintain a table of selectors and values for the function to report.
GestaltValue will eventually be implemented as a standard system trap, in which case, the glue will simply call the trap. Although currently provided as a standalone object file, GestaltValue will eventually be rolled into development libraries; watch for it in a development system near you.
All three GestaltValue functions defined below can move memory, so they cannot be called at interrupt time. But the shared gestalt function that GestaltValue installs in the system heap is reentrant and does not move memory (i.e., it satisfies criteria (2) above), so any values registered via this mechanism can be safely retrieved at interrupt time via the standard Gestalt mechanism.
Interface
Pascal:
FUNCTION NewGestaltValue(selector: OSType;newValue: LONGINT): OSErr;
FUNCTION ReplaceGestaltValue(selector: OSType;replacementValue: LONGINT): OSErr;
FUNCTION DeleteGestaltValue(selector: OSType): OSErr;
C:
pascal OSErr NewGestaltValue (OSType selector, long newValue);
pascal OSErr ReplaceGestaltValue (OSType selector, long replacementValue);
NewGestaltValue and ReplaceGestaltValue are analogous to NewGestalt and ReplaceGestalt. They take a standard 4 character OSType value and a new or replacement value. ReplaceGestaltValue has no parameter analogous to the oldGestaltFunction parameter of ReplaceGestalt. If you desire saving the previous value, you should call Gestalt for that selector before calling ReplaceGestaltValue.
The usual restrictions on the selector parameter still apply. Apple recommends you use your four-character creator sequence for your selector. All lowercase letter and nonalphabetic ASCII sequences are reserved for Apple.
DeleteGestaltValue makes a Gestalt value unknown to Gestalt. Subsequent calls to Gestalt for that selector will return gestaltUndefSelectorErr.
Return values
GestaltValue requires that the _Gestalt trap be implemented. You will get unimpErr (-4) if _Gestalt is unavailable.
NewGestaltValue returns gestaltDupSelectorErr (-5552) if you attempt to add a new value for an existing selector. You should use ReplaceGestaltValue instead.
ReplaceGestaltValue returns gestaltUndefSelectorErr (-5551) if you attempt to replace a non-existent selector. You should use NewGestaltValue instead.
Both NewGestaltValue and ReplaceGestalt value may return memory errors if they cannot allocate sufficient room in the system heap for their code and data.
DeleteGestaltValue returns gestaltUndefSelectorErr if you attempt to delete a selector unknown to GestaltValue (such as a pre-defined gestalt selector such as 'fpu '.